package conference.controller;

import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.io.IOException;
import java.net.ConnectException;

import conference.TCPCommands;
import conference.model.ConferenceState.NOTIFICATION_TYPE;
import conference.model.Client;
import conference.model.ConferenceStateClientSide;
import conference.model.ConferenceStateClientSide.CALL_STATE;
import conference.view.ConferenceGUI;
import javax.swing.JButton;


/**
*
* a controller class handling the button clicks in the client's program.
* @author Samsjo-8
*/
public class ButtonHandling implements ActionListener{//TODO: finish
	
	
	//ConferenceGUI gui;
	ConferenceStateClientSide conference = null;
	public ClientListHandling list = new ClientListHandling();
	ConferenceGUI gui;
	public ClientSideTCP tcp;
	public ButtonHandling thisClass = this;
	//ActionListener listListener()
	
	public ButtonHandling(ConferenceStateClientSide state){
		this.conference=state;
	}
	
	
/**
*
* this class is called when a button click on the buttom buttons has happened
*/
	@Override
	public void actionPerformed(ActionEvent e) {
		
		if(e.getSource()==gui.btConnect){
			if(conference.hasEnteredConference){
				conference.setLeavedConference();
			}else{
				conference.setServerIp(gui.tfIpServer.getText());
				conference.setNickname(gui.tfNickname.getText());
				try {
					connect();
				} catch (IOException e1) {
					e1.printStackTrace();
				} catch (NullPointerException e2){
				}
			}
		}
		
		else if(e.getSource()==gui.btMute){
			if(gui.isMute){
				gui.senderStream.startPipelines();
				gui.btMute.setText("MUTE (OFF)");
				gui.isMute=false;
				
    		}else{
    			gui.senderStream.stopPipelines();
    			gui.btMute.setText("MUTE (ON)");
    			gui.isMute=true;
    		}
			
		}
		
		else if(e.getSource()==gui.btBroadcast){
			//conference.setBroadCaster(conference.getThisClient());
			tcp.send(TCPCommands.client_msg_WANTS_TO_BROADCAST);
		}
		
		else if(e.getSource()==gui.btStop){
			//TODO: add cancel, if calling but not in call
			Client oldClient = conference.getPrivateTalkClient();
			if(oldClient!=null){
				tcp.send(TCPCommands.SIP_msg_BYE+' '+oldClient.toTransferString());
				conference.setCallState(CALL_STATE.NOT_IN_CALL);
			}
		}
		
		else if(e.getSource()==gui.btAcceptCall){
			
			
			//TODO : place here the code to start the communication between the 2 people (it is what we used to do automatically)
			//accept call
			
			//start streaming
			conference.setCallState(CALL_STATE.IN_CALL);
			
			//send accept_private_talk message
			tcp.send(TCPCommands.SIP_msg_OK+' '+conference.getPrivateTalkClient().toTransferString());
			
			
			gui.ring.stop();
			gui.callFrame.setVisible(false); // we close the frame
		}
		
		else if(e.getSource()==gui.btRejectCall){
			//code to send a "call refused" message to the person who made the call
			tcp.send(TCPCommands.SIP_msg_BUSY+' '+conference.getPrivateTalkClient().toTransferString());
			conference.setCallState(CALL_STATE.NOT_IN_CALL);
			gui.ring.stop();
			gui.callFrame.setVisible(false); // we close the frame
		}
		
	}
	
	private void onMute(){
		
	}
	
	private void onJoinLeave(){
		
	}
	
	
/**
*
* This inner class handles the button clicks done in the left-side buttons, namely the buttons representing the participants of the conference
* @author samsjo-8
*/
	private class ClientListHandling implements ActionListener{

		
		public ClientListHandling(){
		}
		

/**
*
* this method is called when a button click has happened on the left-side list. A click on these buttons means the user wants a private talk with the clicked client.
* 
*/
		@Override
		public void actionPerformed(ActionEvent arg0) {
			//change port to
			
			//do private talk request
			JButton bt = ((JButton) (arg0.getSource()));
			String ip = bt.getName(); //get the ip
			//set state that we want to do a call
			try{
				conference.setPrivateTalkClient(ip);
				
			} catch (NullPointerException e){
				System.out.println("Sorry, Client with ip "+ip+" does not exist");
				//ask server for a full list refresh
			}
			conference.setCallState(CALL_STATE.INVITING); //let client start sending invite requests
			
			
		}
		
	}
	
  /**
  * this method has to be called in the initialization phase of the program.
  *
  */
	public void setGUI(ConferenceGUI confGUI){
		this.gui= confGUI;
	}


/**
* called when the user clicks the connect button.
*  
*/
	private void connect() throws IOException{
		new Thread(new Runnable(){
			@Override
			public void run() {
				try {
						tcp = new ClientSideTCP(conference, thisClass);
				} catch (IOException e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				} catch (InterruptedException e) {
						// TODO Auto-generated catch block
						e.printStackTrace();
				}
			}
			
		}).start();
			
	}
	
   
/**
*
* removing the tcp connection thread upon disconnection from server.
*  
*/
	void disconnect(){
		tcp = null;
	}
	
	
	
}
